// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: wsfuyibing <682805@qq.com>
// Date: 2025-02-08

package sell_order

import (
    "context"
    "fmt"
    "integration/app/errs"
    "integration/app/lib/nod/crmeb"
    "integration/app/models"
    "integration/app/services"
    "math"
    "strconv"
    "strings"
)

// Goods
// 商品定义.
type Goods struct {
    GoodsId   int     `json:"goods" label:"商品ID"`
    Quantity  float64 `json:"nums" label:"商品数量"`
    Price     float64 `json:"price" label:"不含税单价"`
    Total     float64 `json:"total" label:"不含税总价"`
    Tax       float64 `json:"tax" label:"税率"`
    TaxAmount float64 `json:"tat" label:"税额"`
    TaxPrice  float64 `json:"tpe" label:"含税单价"`
    TaxTotal  float64 `json:"tpt" label:"价税合计"`
    Warehouse int     `json:"warehouse" label:"仓库ID"`

    Cell     int        `json:"cell" label:"计量单位ID"`
    Data     string     `json:"data" label:"备注"`
    Discount float64    `json:"discount" label:"折扣率"`
    Dsc      float64    `json:"dsc" label:"折扣金额"`
    Field    GoodsField `json:"field" label:"扩展字段"`
    Spec     int        `json:"spec" label:"规格ID"`
}

func NewGoods() *Goods {
    return &Goods{}
}

func (o *Goods) With(ctx context.Context, order *models.Order, info crmeb.CartInfo) (err error) {
    if err = o.loadGoods(ctx, info); err == nil {
        if err = o.loadPrice(info); err == nil {
            o.loadSerialize(order, info)
        }
    }
    return
}

func (o *Goods) loadGoods(ctx context.Context, info crmeb.CartInfo) (err error) {
    var bean *models.ErpGoods
    // 1. 查询商品.
    if bean, err = services.NewErpGoodsService().GetByErpCode(ctx, info.GenerateCode()); err != nil {
        err = errs.ErrDatabaseQueryFailed
        return
    }
    // 2. 从未同步.
    if bean == nil {
        err = errs.ErrErpGoodsNotSync
        return
    }
    // 3. 商品属性.
    o.GoodsId = bean.ErpId
    o.Tax = o.round(bean.ErpTax * 100)
    o.Warehouse = bean.ErpWarehouse
    return
}

func (o *Goods) loadPrice(info crmeb.CartInfo) (err error) {
    var f float64

    // 1. 数值处理.
    if f, err = o.float(info.Quality); err == nil {
        // 销售数量
        o.Quantity = f
        if f, err = o.float(info.Price); err == nil {
            // 含税单价
            o.TaxPrice = o.round(f)
            if f, err = o.float(info.Total); err == nil {
                // 含税总价
                o.TaxTotal = o.round(f)
            }
        }
    }

    // 2. 错误参数.
    if err != nil {
        return
    }

    // 4. 税率为空.
    if n := int(o.Tax); n == 0 {
        o.Price = o.TaxPrice
        o.Total = o.TaxTotal
        return
    }

    // 5. 计算税额.
    o.Price = o.round((100.0 * o.TaxPrice) / (100.0 + o.Tax))
    o.Total = o.round(o.Price * o.Quantity)
    o.TaxAmount = o.round(o.TaxTotal - o.Total)
    return
}

func (o *Goods) loadSerialize(order *models.Order, info crmeb.CartInfo) {
    var serial = make([]string, 0)
    for i := 0; i < int(o.Quantity); i++ {
        serial = append(serial, fmt.Sprintf(`SN-%d-%d-%d`, order.Id, info.Product.Id, i+1))
    }
    if len(serial) > 0 {
        o.Field.A = strings.Join(serial, ",")
    }
}

func (o *Goods) float(src any) (f float64, err error) {
    if f, err = strconv.ParseFloat(fmt.Sprintf(`%v`, src), 64); err == nil {
        f = o.round(f)
    }
    return
}

func (o *Goods) round(v float64) float64 {
    return math.Round(v*100) / 100
}
